package ink.carnation.imtalk.service.impl;

import ink.carnation.imtalk.mapper.FriendMapper;
import ink.carnation.imtalk.mapper.UserMapper;
import ink.carnation.imtalk.model.po.FriendPo;
import ink.carnation.imtalk.model.po.UserPo;
import ink.carnation.imtalk.model.vo.FriendVO;
import ink.carnation.imtalk.service.FriendService;
import ink.carnation.imtalk.service.UserService;
import ink.carnation.imtalk.util.JwtUtil;
import ink.carnation.imtalk.util.TokenCacheKey;
import ink.carnation.imtalk.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
public class FriendServiceImpl implements FriendService {
    @Resource
    private FriendMapper friendMapper;
    @Resource
    private UserService userService;
    @Resource
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public int addFriend(Integer userId, Integer friendId) {
        FriendPo build = FriendPo.builder()
                .userId(userId)
                .friendId(friendId)
                .valid(true)
                .solved(true)
                .build();
        List<FriendPo> select = friendMapper.select(build);
        //好友已存在
        if (!CollectionUtils.isEmpty(select)) {
            return -1;
        }
        build.setSolved(false);
        return friendMapper.insertSelective(build);
    }

    @Override
    @Transactional
    public int confirmAddFriend(Integer userId, Integer friendId) {
        FriendPo build = FriendPo.builder()
                .userId(userId)
                .friendId(friendId)
                .valid(true)
                .solved(true)
                .build();
        //好友已存在
        List<FriendPo> select = friendMapper.select(build);
        if (!CollectionUtils.isEmpty(select)) {
            return -1;
        }
        friendMapper.insertSelective(build);
        return friendMapper.updateAddConfrimFriend(friendId, userId);
    }

    @Override
    @Transactional
    public Boolean deleteFriend(Integer userId, Integer friendId) {
        Example example = new Example(FriendPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId)
                .andEqualTo("friendId", friendId)
                .andEqualTo("solved", true)
                .andEqualTo("valid", true);
        FriendPo build = FriendPo.builder()
                .valid(false)
                .build();
        Example example1 = new Example(FriendPo.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("userId", friendId)
                .andEqualTo("friendId", userId)
                .andEqualTo("solved", true)
                .andEqualTo("valid", true);
        return friendMapper.updateByExampleSelective(build, example) > 0
                && friendMapper.updateByExampleSelective(build, example1) > 0;
    }

    @Override
    public List<UserPo> getFriendByNickName(HttpServletRequest request, String nickName) {
        String token = request.getHeader("Authorization");
        Integer userId = JwtUtil.getUserId(token);
        return friendMapper.selectByNickName(nickName, userId);
    }

    @Override
    public List<FriendVO> getFriendListByUserId(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Integer userId = JwtUtil.getUserId(token);
        List<FriendVO> friendListByUserId = friendMapper.getFriendListByUserId(userId);
        setFriendVOActive(friendListByUserId);
        return friendListByUserId;
    }

    @Override
    public UserPo getFriendByFriendId(HttpServletRequest request, Integer friendId) {
        //根据token拿到userId
        String token = request.getHeader("Authorization");
        Integer userId = JwtUtil.getUserId(token);
        return friendMapper.selectByUserIdAndFriendId(userId, friendId);
    }

    @Override
    public void setFriendVOActive(List<FriendVO> friendVOList) {
        for (FriendVO friendVO : friendVOList) {
            if (redisTemplate.hasKey(TokenCacheKey.getUserTokenKey(friendVO.getId()))) {
                friendVO.setActive(true);
            }
        }
    }

    @Override
    public List<FriendVO> getFriends(Integer userId) {
        List<FriendVO> friendListByUserId = friendMapper.getFriendListByUserId(userId);
        Set<Integer> usersId = WebSocketServer.sessionMap.keySet();
        friendListByUserId.stream().forEach(x->{
            if (usersId.contains(x)) {
                x.setActive(true);
            }else
                x.setActive(false);
        });
        return friendListByUserId;
    }
}
